package com.kxmall.web.controller.riderOrder;

import cn.hutool.core.bean.BeanUtil;
import com.kxmall.common.annotation.Log;
import com.kxmall.common.annotation.RepeatSubmit;
import com.kxmall.common.core.controller.BaseRiderController;
import com.kxmall.common.core.domain.PageQuery;
import com.kxmall.common.core.domain.R;
import com.kxmall.common.core.page.TableDataInfo;
import com.kxmall.common.core.validate.AddGroup;
import com.kxmall.common.core.validate.EditGroup;
import com.kxmall.common.enums.BusinessType;
import com.kxmall.common.enums.RiderStatusType;
import com.kxmall.common.exception.ServiceException;
import com.kxmall.common.core.domain.model.LoginUser;
import com.kxmall.huishou.domain.HsAppointmentOrder;
import com.kxmall.huishou.domain.HsSettlementOrder;
import com.kxmall.huishou.domain.bo.HsAppointmentOrderBo;
import com.kxmall.huishou.domain.bo.HsSettlementOrderBo;
import com.kxmall.huishou.domain.bo.HsUserWasteBo;
import com.kxmall.huishou.domain.vo.HsAppointmentOrderVo;
import com.kxmall.huishou.domain.vo.HsSettlementOrderVo;
import com.kxmall.huishou.domain.vo.HsUserWasteVo;
import com.kxmall.huishou.service.IHsAppointmentOrderService;
import com.kxmall.huishou.service.IHsSettlementOrderService;
import com.kxmall.huishou.service.IHsUserWasteService;
import com.kxmall.rider.domain.KxRider;
import com.kxmall.rider.mapper.KxRiderMapper;
import com.kxmall.system.domain.SysNotice;
import com.kxmall.web.controller.riderNotice.service.IRiderNoticetService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 会员端查看预约订单
 *
 * @author lf
 * @date 2023-12-01
 */

@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/riderAppOrder/app")
public class HsRiderAppOrderController extends BaseRiderController {

    /**
     * 不能取消的订单状态列表
     * 0: 待接单, 1: 其他状态, 5: 已完成
     */
    private static final List<Long> UN_CANCELLABLE_STATUS_LIST = Arrays.asList(0L, 1L, 5L);

    private final IHsAppointmentOrderService iHsAppointmentOrderService;
    private final IHsUserWasteService iHsUserWasteService;
    private final IHsSettlementOrderService iHsSettlementOrderService;
    private final IRiderNoticetService iRiderNoticetService;
    private final KxRiderMapper kxRiderMapper;

    /**
     * 查询订单列表
     */
    @GetMapping("/getOrderPageList")
    public TableDataInfo<HsAppointmentOrderVo> getOrderPageLists(HsAppointmentOrderBo bo, PageQuery pageQuery){

        if(bo == null){
            bo = new HsAppointmentOrderBo();
        }

        if(bo.getStatus() != null && (bo.getStatus() < 0 || bo.getStatus() > 9)){
            bo.setStatus(null);
        }
        if(bo.getStatus() == null || bo.getStatus().longValue() != 0l){
            bo.setRiderId(getRiderLoginUser().getUserId());
        }
        pageQuery.setOrderByColumn("create_time");
        pageQuery.setIsAsc("desc");

        TableDataInfo<HsAppointmentOrderVo> dataList = iHsAppointmentOrderService.queryPageLists(bo,pageQuery);
        if(dataList != null && dataList.getRows() != null){
            for(HsAppointmentOrderVo hsAppointmentOrderVo : dataList.getRows()){

                if(hsAppointmentOrderVo.getStatus().longValue() == 5 || hsAppointmentOrderVo.getStatus().longValue() == 6){
                    long usetime = 0l;
                    if(hsAppointmentOrderVo.getCompleteTime() != null && hsAppointmentOrderVo.getTakingTime() != null){
                        usetime = hsAppointmentOrderVo.getCompleteTime().getTime() - hsAppointmentOrderVo.getTakingTime().getTime();
                    }else if(hsAppointmentOrderVo.getArriveTime() != null && hsAppointmentOrderVo.getTakingTime() != null){
                        usetime = hsAppointmentOrderVo.getArriveTime().getTime() - hsAppointmentOrderVo.getTakingTime().getTime();
                    }

                    if(usetime < 60000l){
                        hsAppointmentOrderVo.setTimeStr("5分钟");
                    }else {
                        long hours = usetime/(3600l*1000l) ;
                        usetime = usetime % (3600l*1000l);
                        long minutes = usetime / (60l*1000l);
                        if(hours > 0){
                            hsAppointmentOrderVo.setTimeStr(hours+"小时"+minutes+"分钟");
                        }else {
                            hsAppointmentOrderVo.setTimeStr(minutes+"分钟");
                        }
                    }
                }

                HsUserWasteBo hsUserWasteBo = new HsUserWasteBo();
                hsUserWasteBo.setOrderId(hsAppointmentOrderVo.getId());
                hsUserWasteBo.setOrderType(0L);
                List<HsUserWasteVo> hsUserWasteVoList = iHsUserWasteService.queryList(hsUserWasteBo);
                hsAppointmentOrderVo.setHsUserWasteVoList(hsUserWasteVoList);
            }
        }

        return dataList;
    }

    /**
     * 获取回收预约订单详细信息
     *
     * @param id 主键
     */
    @GetMapping("/{id}")
    public R<HsAppointmentOrderVo> getInfoById(@NotNull(message = "主键不能为空") @PathVariable Long id) {

        HsAppointmentOrderVo hsAppointmentOrderVo = iHsAppointmentOrderService.queryById(id);
        Long riderId = getRiderLoginUser().getUserId();

        if(hsAppointmentOrderVo != null){
            if(hsAppointmentOrderVo.getStatus().longValue() != 0l && hsAppointmentOrderVo.getRiderId().longValue() != riderId.longValue() ){
                return R.fail("订单信息与用户不匹配");
            }

            HsUserWasteBo hsUserWasteBo = new HsUserWasteBo();
            hsUserWasteBo.setOrderId(hsAppointmentOrderVo.getId());
            hsUserWasteBo.setOrderType(0L);
            List<HsUserWasteVo> hsUserWasteVoList = iHsUserWasteService.queryList(hsUserWasteBo);
            hsAppointmentOrderVo.setHsUserWasteVoList(hsUserWasteVoList);
        }
        return R.ok(hsAppointmentOrderVo);
    }


    /**
     * 新增预约结算订单信息
     */
    @Log(title = "新增结算订单信息", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/addSettleOrder")
    public R<Void> addSettleOrder(@Validated(AddGroup.class) @RequestBody HsSettlementOrderBo bo) {
        Long riderId = getRiderLoginUser().getUserId();
        HsAppointmentOrderVo hsAppointmentOrderVo = iHsAppointmentOrderService.queryById(bo.getAppointOrderId());
        if(hsAppointmentOrderVo == null || hsAppointmentOrderVo.getRiderId() == null || hsAppointmentOrderVo.getRiderId().longValue() != riderId.longValue() ){
            return R.fail("回收预约订单不存在！");
        }

        //查询结算订单是否存在
        HsSettlementOrderBo querry = new HsSettlementOrderBo();
        querry.setAppointOrderId(bo.getAppointOrderId());

        List<HsSettlementOrderVo> hsSettlementOrderVoList = iHsSettlementOrderService.queryList(querry);
        if(hsSettlementOrderVoList != null && hsSettlementOrderVoList.size()>0){
            return R.fail("该预约订单的结算单已存在！");
        }

        bo.setOrderNo("HSJS"+ DateFormatUtils.format(System.currentTimeMillis(),"yyyyMMddHHmmssSSS"));
        bo.setUserId(hsAppointmentOrderVo.getUserId());
        bo.setRiderId(riderId);
        bo.setStatus(0l);
        bo.setLinkType(0);
        boolean flag = iHsSettlementOrderService.insertByBo(bo);
        //结算订单新建成功后通知用户确认
        if(flag){

            //设置结算信息状态
            hsAppointmentOrderVo.setStatusSettlement(1);
            // 将Vo转换为Bo
            HsAppointmentOrderBo hsAppointmentOrderBo = new HsAppointmentOrderBo();
            BeanUtils.copyProperties(hsAppointmentOrderVo, hsAppointmentOrderBo);
            iHsAppointmentOrderService.updateById(hsAppointmentOrderBo);


            SysNotice sysNotice = new SysNotice();
            sysNotice.setNoticeTitle("预约订单"+hsAppointmentOrderVo.getOrderNo()+"结算待确认！");
            sysNotice.setNoticeContent("预约订单"+hsAppointmentOrderVo.getOrderNo()+"已经生成结算信息，等待确认！");
            sysNotice.setNoticeType("1");
            sysNotice.setStatus("0");
            sysNotice.setOrderId(hsAppointmentOrderVo.getId());
            sysNotice.setUserId(hsAppointmentOrderVo.getUserId());
            sysNotice.setUserType(1);
            iRiderNoticetService.save(sysNotice);

        }

        return toAjax(flag);
    }


    /**
     * 新增一键回收订单信息，回收员自主创建回收结算订单进行回收
     */
    @Log(title = "新增一键回收订单信息", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/addOneKeySettleOrder")
    public R<Void> addOneKeySettleOrder(@Validated(AddGroup.class) @RequestBody HsSettlementOrderBo bo) {
        // 验证骑手身份，防止串号
        LoginUser riderUser = getRiderLoginUser();
        Long riderId = riderUser.getUserId();

        // 验证骑手类型和设备类型
        if (!"rider_user".equals(riderUser.getUserType())) {
            throw new ServiceException("用户类型不正确，请使用骑手账号登录");
        }

        // 验证LoginId格式
        String expectedLoginId = "rider_user:" + riderId;
        String actualLoginId = cn.dev33.satoken.stp.StpUtil.getLoginIdAsString();
        if (!expectedLoginId.equals(actualLoginId)) {
            log.error("骑手身份验证失败 - 期望LoginId: {}, 实际LoginId: {}", expectedLoginId, actualLoginId);
            throw new ServiceException("骑手身份验证失败，请重新登录");
        }

        log.info("骑手创建一键回收订单 - 骑手ID: {}, LoginId: {}", riderId, actualLoginId);

        if(bo.getPayType() >4 || bo.getPayType() <0){
            return R.fail("支付方式错误！");
        }

        bo.setOrderNo("HSJS"+ DateFormatUtils.format(System.currentTimeMillis(),"yyyyMMddHHmmssSSS"));
        bo.setRiderId(riderId);
        bo.setStatus(4l);
        bo.setLinkType(1);
        boolean flag = iHsSettlementOrderService.insertByBo(bo);

        return toAjax(flag);
    }

    /**
     * 处理结算订单信息
     */
    @Log(title = "处理结算订单信息", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/dealSettleOrderByRider")
    public R<Void> dealSettleOrderByRider(@Validated(EditGroup.class) @RequestBody HsSettlementOrderBo bo) {
        Long riderId = getRiderLoginUser().getUserId();
        //查询结算订单是否存在
        HsSettlementOrderVo hsSettlementOrderVo = iHsSettlementOrderService.queryById(bo.getId());
        if(hsSettlementOrderVo == null || hsSettlementOrderVo.getRiderId() == null || hsSettlementOrderVo.getRiderId().longValue() != riderId.longValue() ){
            return R.fail("订单不存在！");
        }
        bo.setOrderNo(hsSettlementOrderVo.getOrderNo());
        bo.setUserId(hsSettlementOrderVo.getUserId());
        bo.setLinkType(0);
        //判断处理逻辑
        if(bo.getStatus() == null){
            return R.fail("处理逻辑状态为空");
        }

        if(hsSettlementOrderVo.getStatus() == null){
            return R.fail("逻辑状态为空");
        }
        //如果订单状态为结算中，回收员可以取消
        else if(hsSettlementOrderVo.getStatus().longValue() == 0l){
            if(bo.getStatus().longValue() != 6l){
                return R.fail("该状态只能取消，无法其他操作！");
            }

        }

        //如果订单状态为用户已确认，回收员可以确认支付，也可以取消
        else if(hsSettlementOrderVo.getStatus().longValue() == 1l){
            if(bo.getStatus().longValue() != 3l && bo.getStatus().longValue() != 6l){
                return R.fail("该状态只能确认支付或取消，无法其他操作！");
            }

        }

        //如果订单状态为用户取消结算，回收员可以重新编辑提交，也可以直接取消订单
        else if(hsSettlementOrderVo.getStatus().longValue() == 2l){
            if(bo.getStatus().longValue() != 0l && bo.getStatus().longValue() != 6l){
                return R.fail("该状态只能重新提交或取消，无法其他操作！");
            }
        }

        //如果订单状态为用户取消结算，回收员可以重新编辑提交，也可以直接取消订单
        else if(hsSettlementOrderVo.getStatus().longValue() == 5l){
            if(bo.getStatus().longValue() != 3l && bo.getStatus().longValue() != 6l){
                return R.fail("该状态只能重新支付或取消，无法其他操作！");
            }
        }else {
            return R.fail("该状态无法操作！");
        }

        HsSettlementOrder hsSettlementOrder = new HsSettlementOrder();
        BeanUtils.copyProperties(bo,hsSettlementOrder);
        boolean flag = iHsSettlementOrderService.updateById(hsSettlementOrder);

        //结束预约订单
        if(flag && bo.getStatus().longValue() == 6l){

            HsAppointmentOrder appointmentOrder = new HsAppointmentOrder();
            appointmentOrder.setId(bo.getAppointOrderId());
            appointmentOrder.setRiderId(riderId);
            appointmentOrder.setStatus(7l);
            appointmentOrder.setCompleteTime(new Date());
            iHsAppointmentOrderService.dealOrderByRider(appointmentOrder);
        }

        if(flag){

            SysNotice sysNotice = new SysNotice();
            if(bo.getStatus().longValue() == 0l){
                sysNotice.setNoticeTitle("结算订单"+hsSettlementOrderVo.getOrderNo()+"已重新提交，待确认！");
                sysNotice.setNoticeContent("结算订单"+hsSettlementOrderVo.getOrderNo()+"已重新提交，等待信息确认！");
            }else if(bo.getStatus().longValue() == 3l){
                sysNotice.setNoticeTitle("结算订单"+hsSettlementOrderVo.getOrderNo()+"已提交支付，待确认！");
                sysNotice.setNoticeContent("结算订单"+hsSettlementOrderVo.getOrderNo()+"已提交支付，等待确认支付！");
            }else if(bo.getStatus().longValue() == 6l){
                sysNotice.setNoticeTitle("结算订单"+hsSettlementOrderVo.getOrderNo()+"已被回收员取消！");
                sysNotice.setNoticeContent("结算订单"+hsSettlementOrderVo.getOrderNo()+"已被回收员取消，结算失败！");
            }else {
                sysNotice = null;
            }

            if(sysNotice != null){
                sysNotice.setNoticeType("1");
                sysNotice.setStatus("0");
                sysNotice.setOrderId(hsSettlementOrderVo.getId());
                sysNotice.setUserId(hsSettlementOrderVo.getUserId());
                sysNotice.setUserType(1);
                iRiderNoticetService.save(sysNotice);
            }

        }

        return toAjax(flag);
    }

    /**
     * 根据预约订单id获取结算订单信息
     *
     * @param appointOrderId
     */
    @GetMapping("/getSettleOrderBy/{appointOrderId}")
    public R<HsSettlementOrderVo> geOrderByAppointOrderId(@NotNull(message = "主键不能为空")
                                                          @PathVariable Long appointOrderId) {
        HsSettlementOrderBo hsSettlementOrderBo = new HsSettlementOrderBo();
        hsSettlementOrderBo.setAppointOrderId(appointOrderId);
        hsSettlementOrderBo.setRiderId(getRiderLoginUser().getUserId());

        List<HsSettlementOrderVo> hsSettlementOrderVoList = iHsSettlementOrderService.queryList(hsSettlementOrderBo);
        HsSettlementOrderVo hsSettlementOrderVo = null;
        if(hsSettlementOrderVoList != null && hsSettlementOrderVoList.size()>0){
            hsSettlementOrderVo = hsSettlementOrderVoList.get(0);
        }

        if(hsSettlementOrderVo != null){
            HsUserWasteBo hsUserWasteBo = new HsUserWasteBo();
            hsUserWasteBo.setOrderId(hsSettlementOrderVo.getId());
            hsUserWasteBo.setOrderType(1L);
            List<HsUserWasteVo> hsUserWasteVoList = iHsUserWasteService.queryList(hsUserWasteBo);
            hsSettlementOrderVo.setHsUserWasteVoList(hsUserWasteVoList);
        }

        return R.ok(hsSettlementOrderVo);
    }

    /**
     * 处理订单,接单，取消，确认到达
     */
    @Log(title = "处理订单", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @GetMapping("/dealOrder")
    public R<Void> takeOrder(HsAppointmentOrderBo bo) {

        if(bo == null || bo.getId() == null || bo.getStatus() == null){
            return R.fail("参数错误");
        }

        HsAppointmentOrderVo hsAppointmentOrderVo = iHsAppointmentOrderService.queryById(bo.getId());
        if(hsAppointmentOrderVo == null){
            return R.fail("订单不存在");
        }

        // 验证骑手身份，防止串号
        LoginUser riderUser = getRiderLoginUser();
        Long riderId = riderUser.getUserId();

        // 验证骑手类型
        if (!"rider_user".equals(riderUser.getUserType())) {
            throw new ServiceException("用户类型不正确，请使用骑手账号登录");
        }

        // 验证LoginId格式
        String expectedLoginId = "rider_user:" + riderId;
        String actualLoginId = cn.dev33.satoken.stp.StpUtil.getLoginIdAsString();
        if (!expectedLoginId.equals(actualLoginId)) {
            log.error("骑手身份验证失败 - 期望LoginId: {}, 实际LoginId: {}", expectedLoginId, actualLoginId);
            throw new ServiceException("骑手身份验证失败，请重新登录");
        }

        log.info("骑手处理订单 - 骑手ID: {}, 订单ID: {}, 操作状态: {}", riderId, bo.getId(), bo.getStatus());
        KxRider kxRider = kxRiderMapper.selectById(riderId);
        if(kxRider == null){
            throw new ServiceException("账号已被禁用");
        }
        if (kxRider.getState() == RiderStatusType.ABORT.getCode()) {
            throw new ServiceException("骑手处于禁用状态，请联系管理员");
        }
        HsAppointmentOrder appointmentOrder = new HsAppointmentOrder();
        appointmentOrder.setId(bo.getId());
        appointmentOrder.setRiderId(riderId);
        //如果是回收员接单，要判断订单是否是待接单状态
        if(bo.getStatus().longValue() == 2l){
            if(hsAppointmentOrderVo.getStatus().longValue() != 0l){
                return R.fail("订单已被接单或取消");
            }
            appointmentOrder.setStatus(bo.getStatus());
            appointmentOrder.setTakingTime(new Date());

        }
        //如果是回收员取消订单，要判断订单是否未完成且订单属于该回收员
        else if(bo.getStatus().longValue() == 3l){
            // 检查订单状态是否在不能取消的列表中
            if(UN_CANCELLABLE_STATUS_LIST.contains(hsAppointmentOrderVo.getStatus().longValue())){
                return R.fail("当前订单状态无法取消");
            }

            // 检查订单是否属于该回收员（只有已接单的订单才有riderId）
            if(hsAppointmentOrderVo.getStatus().longValue() >= 2l && hsAppointmentOrderVo.getRiderId().longValue() != riderId.longValue()){
                return R.fail("当前订单不属于您，无法取消");
            }

            appointmentOrder.setStatus(0l);
            appointmentOrder.setRiderId(0l);

        }
        //如果是回收员确认达到，要判断订单是否是已接单，待服务状态且订单属于该回收员
        else if(bo.getStatus().longValue() == 4l){
            if(hsAppointmentOrderVo.getStatus().longValue() != 2l || hsAppointmentOrderVo.getRiderId().longValue() != riderId.longValue() ){
                return R.fail("当前订单无权限操作");
            }
            appointmentOrder.setStatus(bo.getStatus());
            appointmentOrder.setArriveTime(new Date());

        }else {
            return R.fail("订单操作状态错误");
        }

        boolean flag = iHsAppointmentOrderService.dealOrderByRider(appointmentOrder);

        if(flag){
            SysNotice sysNotice = new SysNotice();
            if(bo.getStatus().longValue() == 2l){
                sysNotice.setNoticeTitle("预约订单"+hsAppointmentOrderVo.getOrderNo()+"已被接单！");
                sysNotice.setNoticeContent("预约订单"+hsAppointmentOrderVo.getOrderNo()+"已被接单，等待上门服务！");
            }else if(bo.getStatus().longValue() == 3l) {
                sysNotice.setNoticeTitle("预约订单"+hsAppointmentOrderVo.getOrderNo()+"已被取消接单！");
                sysNotice.setNoticeContent("预约订单"+hsAppointmentOrderVo.getOrderNo()+"已被取消接单，等待其他回收员接单！");
            }else if(bo.getStatus().longValue() == 4l) {
                sysNotice.setNoticeTitle("预约订单"+hsAppointmentOrderVo.getOrderNo()+"回收员到达！");
                sysNotice.setNoticeContent("预约订单"+hsAppointmentOrderVo.getOrderNo()+"回收员到达目的地，正在进行服务！");
            }

            sysNotice.setNoticeType("1");
            sysNotice.setStatus("0");
            sysNotice.setOrderId(hsAppointmentOrderVo.getId());
            sysNotice.setUserId(hsAppointmentOrderVo.getUserId());
            sysNotice.setUserType(1);
            iRiderNoticetService.save(sysNotice);

        }


        return toAjax(flag);
    }

    /**
     * 删除结算订单子信息
     *
     * @param ids 主键串
     */
    @Log(title = "删除结算订单子信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/delHsWasteById/{ids}")
    public R<Void> removeHsWasteById(@NotEmpty(message = "主键不能为空")
                                     @PathVariable Long[] ids) {
        Long userId = getRiderLoginUser().getUserId();
        return toAjax(iHsUserWasteService.deleteWithValidByIds(Arrays.asList(ids), true, userId, 1l));
    }



    /**
     * 查询结算订单列表
     */
    @GetMapping("/getSettlementOrderPageList")
    public TableDataInfo<HsSettlementOrderVo> getSettlementOrderPageList(HsSettlementOrderBo bo, PageQuery pageQuery){

        if(bo == null){
            bo = new HsSettlementOrderBo();
        }
        bo.setRiderId(getRiderLoginUser().getUserId());
        if(bo.getStatus() != null && (bo.getStatus() < 0 || bo.getStatus() > 6)){
            bo.setStatus(null);
        }
        pageQuery.setOrderByColumn("create_time");
        pageQuery.setIsAsc("desc");

        return iHsSettlementOrderService.queryPageList(bo,pageQuery);
    }


    /**
     * 获取结算订单详细信息
     *
     * @param id 主键
     */
    @GetMapping("/getSettlementOrderById/{id}")
    public R<HsSettlementOrderVo> getSettlementOrderById(@NotNull(message = "主键不能为空") @PathVariable Long id) {

        HsSettlementOrderVo hsSettlementOrderVo = iHsSettlementOrderService.queryById(id);
        Long riderId = getRiderLoginUser().getUserId();

        if(hsSettlementOrderVo != null){
            if(hsSettlementOrderVo.getRiderId().longValue() != riderId.longValue()){

                return R.fail("订单信息与回收员不匹配");
            }
            HsUserWasteBo hsUserWasteBo = new HsUserWasteBo();
            hsUserWasteBo.setOrderId(id);
            hsUserWasteBo.setOrderType(1L);
            List<HsUserWasteVo> hsUserWasteVoList = iHsUserWasteService.queryList(hsUserWasteBo);
            hsSettlementOrderVo.setHsUserWasteVoList(hsUserWasteVoList);
        }
        return R.ok(hsSettlementOrderVo);
    }


}
